package com.fairytask.scene
{
	import com.fairytask.data.Modulator;
	import com.fairytask.event.SceneEvent;
	import com.fairytask.objects.Cell;
	import com.fairytask.objects.Player;
	import com.fairytask.objects.Virus;
	import com.fairytask.resource.ResManager;
	import com.fairytask.resource.StaticIni;
	import com.fairytask.utils.Vec2D;
	
	import de.polygonal.ds.SLinkedList;
	import de.polygonal.ds.SListIterator;
	
	import starling.display.Image;
	import starling.display.Sprite;

	/**
	 * 游戏场景 
	 * @author game
	 * 做一个单例 一次只出现一个战斗场景
	 */	
	public class BattleScene extends Sprite implements IScene
	{
		private static var _instance	:BattleScene;
		private var sceneData:Object;
		
		//本场景玩家数
		private var players:Vector.<Player>;
		private var model	:Modulator;
		private var rings		:Array=[];
		private var ringsContainer:Sprite;
		private var viruses:SLinkedList;
		private var cells:SLinkedList;
		private var curCell:Cell;
		private static var unitTypes:Vector.<Object>;
		private var difficulty:uint; //难度
		private var maxDifficulty:uint; //最高难度
		private var lineContainer:Sprite;
		private var selectedCells:Array;
		
		public static function get instance():BattleScene
		{
			if(null==_instance)
			{
				_instance	=	new BattleScene();
			}
			return _instance;
		}
		
		public function BattleScene()
		{
			super();
			model	=	Modulator.instance;
			ringsContainer	=	new Sprite();
			viruses	=	new SLinkedList();
			cells		=	new SLinkedList();
			players = new Vector.<Player>;
			lineContainer = new Sprite();
			selectedCells = new Array();
		}
		
		/**
		 * 根据ID来完成场景搭建 
		 * @param pSid
		 * 
		 */
		public function initById(pSid:int):void
		{
			sceneData		=	StaticIni.getIniObj(pSid.toString());
			var pCount:int	=	sceneData["Players"];
			while(pCount>0)
			{
				players.push(new Player());
				pCount--;
			}
			//取得列表
			var cellList	:Array	=	sceneData["CellListID"].split(",");
			while(cellList.length>0)
			{
				var tmpData	:Object	=	StaticIni.getIniObj(cellList.shift());
				var cell	:Cell	=	new Cell(ResManager.getAtlasTexture("popSheet","2"));
				cell.x	=	tmpData.x;
				cell.y	=	tmpData.y;
				cell.init(Number(tmpData.Scale), Number(tmpData.Scale));
				addChild(cell as Sprite);
			}
		}
		
		/**
		 * 更新战斗场景 
		 * @param pElapsed
		 * @param pCurTime
		 * 
		 */
		public function update(pElapsed:Number,pCurTime:Number):void
		{
			//清理选中环
			while(rings.length>0)
			{
				ringsContainer.removeChild(rings.shift());
			}
			var virusesIterator	:SListIterator	=	new SListIterator(viruses, viruses.head);
			var tmpVirus			:Virus;
			var cellsList			:SListIterator;
			var tmpCell			:Cell;
			var tmpVec			:Vec2D;
			var subVec			:Vec2D;
			var squareRadius	:int;
			var hypotenuse		:Number;
			while (virusesIterator.hasNext())
			{
				tmpVirus = virusesIterator.data as Virus;
				tmpVirus.updateMove(pCurTime);
				cellsList = new SListIterator(cells, cells.head);
				while (cellsList.hasNext())
				{
					tmpCell = cellsList.data as Cell;
					tmpVec = tmpCell.vec;
					subVec = tmpVec.subVec(tmpVirus.posV);
					squareRadius = tmpCell.radius * tmpCell.radius;
					hypotenuse = subVec.len2;
					if (hypotenuse <= squareRadius + tmpVirus.feelerDist)
					{
						if (tmpCell == tmpVirus.toCell)
						{
							if (hypotenuse <= squareRadius)
							{
								tmpCell.ov = tmpVirus.ov.vec;
								tmpCell.vel = tmpCell.vel + (1 - tmpCell.radius / 100) * tmpVirus.value;
								if (tmpCell.unitType != tmpVirus.unitType)
								{
									tmpCell.numUnits = tmpCell.numUnits - tmpVirus.value;
									if (tmpCell.numUnits <= 0)
									{
										tmpCell.numUnits = 0;
										tmpCell.unitType = tmpVirus.unitType;
										createClickRing(tmpCell);
										tmpCell.playScaleEffect();
									}
								}
								else
								{
									tmpCell.numUnits = tmpCell.numUnits + tmpVirus.value;
								}
								//TODO 声音处理
								if (contains(tmpVirus))
								{
									removeChild(tmpVirus);
								}
								virusesIterator.remove();
							}
						}
						else if (tmpCell != tmpVirus.fromCell)
						{
							tmpVirus.veerFrom(subVec, squareRadius, hypotenuse);
						}
					}
					cellsList.next();
				}
				for each (var tmpPlayer:Player in players)
				{
					if (tmpVirus.unitType == tmpPlayer.unitType)
					{
						tmpPlayer.numUnits++;
					}
				}
				tmpVirus.update(pCurTime);
				virusesIterator.next();
			}
			curCell = null;
			
			//========================================================================
			//var virusesIterator	:SListIterator	=	new SListIterator(viruses, viruses.head);
			while (cellsList.hasNext())
			{
				tmpCell = cellsList.data as Cell;
				_loc_14 = new SListIterator(cells, cells.head);
				while (_loc_14.hasNext())
				{
					
					_loc_15 = _loc_14.data as Cell;
					if (tmpCell != _loc_15)
					{
						_loc_16 = tmpCell.vec.subVec(_loc_15.vec);
						_loc_17 = tmpCell.radius + _loc_15.radius;
						_loc_18 = _loc_16.len2;
						if (_loc_18 <= _loc_17 * _loc_17 + 2)
						{
							tmpCell.ov.angle = _loc_16.angle;
							_loc_15.ov.angle = _loc_16.reverse.angle;
							tmpCell.vel = (1 - _loc_16.len2 / (_loc_17 * _loc_17)) * 100 + 1;
							_loc_15.vel = (1 - _loc_16.len2 / (_loc_17 * _loc_17)) * 100 + 1;
						}
					}
					_loc_14.next();
				}
				for each (_loc_4 in players)
				{
					
					if (tmpCell.unitType == _loc_4.unitType)
					{
						var _loc_25:* = _loc_4;
						var _loc_26:* = _loc_4.numCell + 1;
						_loc_25.numCell = _loc_26;
					}
				}
				if (difficulty / maxDifficulty > 0.8)
				{
					if (tmpCell.unitType != -1 && tmpCell.unitType != players[0].unitType)
					{
						tmpCell.showUnits = false;
					}
					else
					{
						tmpCell.showUnits = true;
					}
				}
				tmpCell.updateMove(param1, param2);
				if (tmpCell.hitTestPoint(mouseX, mouseY, true))
				{
					curCell = tmpCell;
				}
				cellsList.next();
			}
			var _loc_7:* = 0;
			for each (_loc_4 in players)
			{
				
				if (!contains(tutorialMC))
				{
					_loc_4.update(param1, param2);
				}
				if (_loc_4.hasLost())
				{
					_loc_7++;
				}
			}
			if (players[0].hasLost())
			{
				endMap(false);
				
			}
			if (_loc_7 >= (players.length - 1) && !players[0].hasLost())
			{
				endMap();
				
			}
			if (!input)
			{
				
			}
			if (mouseDown)
			{
				mouseDownTime = mouseDownTime + param2;
			}
			else
			{
				mouseDownTime = 0;
			}
			if (readyToClear)
			{
				lineContainer.graphics.clear();
				lineContainer.graphics.lineStyle(4, 10066329);
				readyToClear = false;
			}
			if (curCell)
			{
				if (curCell.unitType == players[0].unitType || selectedCells.length > 0)
				{
					lineContainer.graphics.drawCircle(curCell.x, curCell.y, curCell.radius + 5);
					readyToClear = true;
				}
				if (mouseDownTime > minMouseDownTime && curCell.unitType == players[0].unitType && selectedCells.length > 0 && selectedCells.indexOf(curCell) == -1 && selectedCells.length < maxSelectableCells)
				{
					selectedCells.push(curCell);
					if (Main.SOUND)
					{
						selectSnd.play(0, 0, selectSndTrans);
					}
					createClickRing(curCell);
				}
			}
			for each (tmpCell in selectedCells)
			{
				
				readyToClear = true;
				if (tmpCell != curCell)
				{
					lineContainer.graphics.drawCircle(tmpCell.x, tmpCell.y, tmpCell.radius + 5);
				}
				if (tmpCell.unitType != players[0].unitType)
				{
					selectedCells.splice(selectedCells.indexOf(tmpCell), 1);
				}
				_loc_20 = tmpCell.vec;
				if (curCell)
				{
					_loc_19 = curCell.vec;
					_loc_22 = _loc_20.subVec(_loc_19);
					_loc_21 = _loc_20.subVec(_loc_19);
					_loc_21.normalize();
					_loc_22.normalize();
					_loc_21.mulN(tmpCell.radius + 5);
					_loc_22.mulN(curCell.radius + 5);
					lineContainer.graphics.moveTo(tmpCell.x - _loc_21.x, tmpCell.y - _loc_21.y);
					lineContainer.graphics.lineTo(_loc_19.x + _loc_22.x, _loc_19.y + _loc_22.y);
					continue;
				}
				_loc_19 = new Vec2D(mouseX, mouseY);
				_loc_21 = _loc_20.subVec(_loc_19);
				_loc_21.normalize();
				_loc_21.mulN(tmpCell.radius + 5);
				lineContainer.graphics.moveTo(tmpCell.x - _loc_21.x, tmpCell.y - _loc_21.y);
				lineContainer.graphics.lineTo(_loc_19.x, _loc_19.y);
			}
		}
		
		/**
		 * 创建Cell的外圈 
		 * @param pCell
		 * 
		 */
		private function createClickRing(pCell:Cell) : void
		{
			if (!pCell)
			{
				return;
			}
			var tmpRing:Image = new Image(ResManager.getAtlasTexture("popSheet","5"));
			tmpRing.x = pCell.x;
			tmpRing.y = pCell.y;
			tmpRing.width = pCell.radius * 3;
			tmpRing.height = pCell.radius * 3;
			ringsContainer.addChild(tmpRing);
			rings.push(tmpRing);
		}
		
		public function start(pId:int=0):void
		{
			initById(pId);
			model.dispatchEvent(new SceneEvent(SceneEvent.START_SCENE,instance));
		}
		
		public function depose():void
		{
			
		}
		
		public function getUnitTypes() : Vector.<Object>
		{
			return unitTypes;
		}
		
		public static function getUnitType(param1:int) : Object
		{
			if (param1 >= unitTypes.length || param1 < 0)
			{
				return null;
			}
			return unitTypes[param1];
		}
		
		/**
		 * 取得难度 
		 * @return 
		 */
		public function get diff() : uint
		{
			return difficulty;
		}
		
		/**
		 * 设置难度 
		 * @param param1
		 * 
		 */
		public function set diff(pDiff:uint) : void
		{
			difficulty = pDiff;
			if (difficulty < 1)
			{
				difficulty = 1;
			}
			else if (difficulty >= maxDifficulty)
			{
				difficulty = maxDifficulty;
			}
		}
		/**
		 * 取得最大难度 
		 * @return 
		 * 
		 */
		public function get maxDiff() : uint
		{
			return maxDifficulty;
		}
		/**
		 * 取得所有玩家 
		 * @return 
		 * 
		 */
		public function get allPlayers() : Vector.<Player>
		{
			return players;
		}
		
		/**
		 * 生成病毒  
		 * @param fCell
		 * @param tCell
		 * @param pCount
		 * 
		 */
		public function createViruses(fCell:Cell, tCell:Cell, pCount:uint = 20) : void
		{
			var tmpVirus:Virus = null;
			var tmpVec:Vec2D = null;
			while (pCount>0)
			{
				tmpVirus = new Virus();
				tmpVec = fCell.randVec;
				tmpVirus.x = tmpVec.x;
				tmpVirus.y = tmpVec.y;
				tmpVirus.fromCell = fCell;
				tmpVirus.toCell = tCell;
				tmpVirus.unitType = fCell.unitType;
				addChild(tmpVirus);
				viruses.append(tmpVirus);
				fCell.vel = fCell.vel + (1 - fCell.radius / 100) * tmpVirus.value * 0.5;
				fCell.ov.vec = tmpVirus.ov;
				pCount--;
			}
			
		}
	}
}